from fastapi import HTTPException, status
from sqlalchemy.exc import SQLAlchemyError

from handle.handle_log import log
from server.controller.log import create_log
from server.db.models.system import Menu


def menu_add(request, createData, db, current_user):
    """
    添加菜单
    :param current_user:
    :param request:
    :param createData:
    :param db:
    :return:
    """
    existing_user = db.query(Menu).filter(
        Menu.name == createData.name,
        Menu.is_deleted == False
    ).first()
    if existing_user:
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params=str(createData),
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=1400,
            response="菜单已存在"
        )
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail={
                "code": 1400,
                "msg": "菜单已存在",
            }
        )

    try:
        new_menu = Menu(
            name=createData.name,
            permission=createData.permission,
            path=createData.path,
            icon=createData.icon,
            order=createData.order,
            parent_id=createData.parent_id,
            is_active=createData.is_active,
            is_deleted=createData.is_deleted,
        )
        db.add(new_menu)
        db.commit()
        db.refresh(new_menu)
    except SQLAlchemyError as e:
        log.error(e)
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params=str(createData),
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=1500,
            response="系统错误"
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "code": 1500,
                "msg": "系统错误",
            }
        )

    else:
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params=str(createData),
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=200,
            response="操作成功"
        )
        return {"code": 200, "msg": "操作成功"}




def build_tree(items, parent_id=None):
    """
    递归构建多层树形结构

    参数:
        items: 原始数据列表
        parent_id: 当前处理的父节点ID，None/空字符串表示根节点

    返回:
        嵌套的多层树形结构列表
    """


    # 找出所有parent_id匹配的项（处理空字符串和None情况）
    children = [item for item in items
                if str(item.get('parent_id', '')) == str(parent_id if parent_id is not None else '')]

    if not children:
        return None

    tree = []
    for child in children:
        # 创建当前节点
        node = {
            'name': child['name'],
            'id': child['id'],
            'order': int(child['order']),  # 转换为整数
            'is_active': child['is_active'].lower() == 'true',  # 转换为布尔值
            'is_deleted': child['is_deleted'].lower() == 'false',  # 转换为布尔值
            'updated_at': child['updated_at'],
            'created_at': child['created_at'],
            'path': child['path'],
            'icon': child['icon'],
            'children_menu': []
        }

        # 递归查找子节点
        sub_items = build_tree(items, child['id'])
        if sub_items:
            node['children_menu'] = sub_items  # 使用'children'作为子节点键名

        tree.append(node)

    # 按order字段排序
    tree.sort(key=lambda x: x['order'])
    return tree


def convert_to_nested_structure(data):
    """
    转换入口函数

    参数:
        data: 原始数据列表

    返回:
        嵌套的多层树形结构
    """
    # 找出所有根节点（parent_id为空或不存在）
    root_items = [item for item in data if not item.get('parent_id', '')]

    if not root_items:
        return []

    # 构建完整树结构
    result = []
    for root in root_items:
        root_node = {
            'name': root['name'],
            'id': root['id'],
            'order': int(root['order']),
            'is_active': root['is_active'].lower() == 'true',
            'is_deleted': root['is_deleted'].lower() == 'false',
            'updated_at': root['updated_at'],
            'created_at': root['created_at'],
            'path': root['path'],
            'icon': root['icon'],
            "children": []
        }

        # 递归构建子树
        children = build_tree(data, root['id'])
        if children:
            root_node['children'] = children

        result.append(root_node)

    # 按order字段排序
    result.sort(key=lambda x: x['order'])
    return result


def get_menu_tree(request,  db, current_user):


    """获取菜单树"""
    menu_list = []
    try:
        menu_all = db.query(Menu).filter(Menu.is_deleted == False).all()
    except SQLAlchemyError as e:
        log.error(e)
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params="",
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=1500,
            response="系统错误"
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "code": 1500,
                "msg": "系统错误",
            }
        )
    else:
        for menu in menu_all:
            menu_list.append({f"{k}":f"{v}" for k, v in menu.__dict__.items() if k != "_sa_instance_state" })
        rest = convert_to_nested_structure(menu_list)
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params="",
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=200,
            response="操作成功"
        )
        return {
            "data": rest,
            "code": 200,
            "msg": "操作成功",
        }


def menu_update(request, updateDate, db, current_user):
    """
    更新菜单
    :param request:
    :param updateDate:
    :param db:
    :return:
    """
    try:
        db.query(Menu).filter(Menu.id == updateDate.id).update(
            {
                Menu.name: updateDate.name,
                Menu.icon: updateDate.icon,
                Menu.order: updateDate.order,
                Menu.is_active: updateDate.is_active,
                Menu.path: updateDate.path
            }
        )
        db.commit()
    except SQLAlchemyError as e:
        log.error(e)
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params=str(updateDate),
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=1500,
            response="系统错误"
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "code": 1500,
                "msg": "系统错误",
            }
        )
    else:
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params=str(updateDate),
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=200,
            response="操作成功"
        )
        return {"code": 200, "msg": "操作成功"}


def menu_delete(request, deleteData, db, current_user):
    """
    删除菜单
    :param request:
    :param deleteData:
    :param db:
    :return:
    """
    try:
        db.query(Menu).filter(Menu.id == deleteData.id and Menu.is_deleted == False).update(
            {
                Menu.is_deleted: True
            }
        )
        db.commit()
    except SQLAlchemyError as e:
        log.error(e)
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params=str(deleteData),
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=1500,
            response="系统错误"
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail={
                "code": 1500,
                "msg": "系统错误",
            }
        )
    else:
        create_log(
            db=db,
            user_id=current_user,
            method=request.method,
            path=str(request.url),
            params=str(deleteData),
            ip_address=request.client.host,
            user_agent=request.headers.get('User-Agent'),
            status_code=200,
            response="操作成功"
        )
        return {"code": 200, "msg": "操作成功"}